﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
using System.Runtime.Remoting;
using System.Diagnostics;

namespace SEAM.Core
{
    public class ObjectFactory
    {
        public static object CreateObject(string format, params object[] args)
        {
            if (string.IsNullOrEmpty(format))
                return null;

            try
            {
                // if there are multiple tokens in the string, we assume that the first token
                // represents the Type, second token represents the Assembly.
                string[] tokens = format.Split(',');
                string typeName = tokens[0];
                string assemblyName = (tokens.Length > 1 ? tokens[1] : null);
                ObjectHandle objHandle = Activator.CreateInstance(assemblyName, typeName, true, BindingFlags.Default, null, args, null, null, null);
                return objHandle.Unwrap();
            }
            catch (System.Exception ex) 
            {
                Trace.TraceWarning(ex.Message + Environment.NewLine + ex.StackTrace);
            }

            return null;
        }

        public static List<string> GetPropertyNames(object obj)
        {
            List<string> props = new List<string>();
            PropertyInfo[] properties = obj.GetType().GetProperties();

            foreach (PropertyInfo pi in properties)
                props.Add(pi.Name);

            return props;
        }

        public static void SetValue<T>(ref T objSource, string propertyName, object value)
        {
            //1. determine the type of the property
            //2. cast the type of the value to that of the property
            //3. assgign the value to the object

            Type propertyType = objSource.GetType().GetProperty(propertyName).GetValue(objSource, null).GetType();

            value = Convert.ChangeType(value, propertyType);

            objSource.GetType().GetProperty(propertyName).SetValue(objSource, value, null);
        }
    }
}
